package dao

import (
	"context"
	"errors"
	"time"

	"github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
)

var (
	ErrDuplicateUsername = errors.New("用户名冲突")
	ErrRecordNotFound    = gorm.ErrRecordNotFound
)

type UserDAO interface {
	Create(ctx context.Context, user User) error
	FindByUsername(ctx context.Context, username string) (User, error)
}

type GROMUserDAO struct {
	db *gorm.DB
}

// NewGROMUserDAO 创建 GROMUserDAO 实例
func NewGROMUserDAO(db *gorm.DB) UserDAO {
	return &GROMUserDAO{
		db: db,
	}
}

// Create 创建用户
func (dao *GROMUserDAO) Create(ctx context.Context, user User) error {
	now := time.Now().Unix()
	user.CTime = now
	user.UTime = now
	err := dao.db.WithContext(ctx).Create(&user).Error
	if me, ok := err.(*mysql.MySQLError); ok {
		const duplicateErr uint16 = 1062
		if me.Number == duplicateErr {
			// 用户冲突
			return ErrDuplicateUsername
		}
	}
	return err
}

// FindByUsername 根据用户名查找用户
func (dao *GROMUserDAO) FindByUsername(ctx context.Context, username string) (User, error) {
	var user User
	err := dao.db.WithContext(ctx).Where("username = ?", username).First(&user).Error
	return user, err
}

// User 数据库用户表
type User struct {
	ID       int64  `json:"id" gorm:"primaryKey;autoIncrement"`
	Username string `json:"username" gorm:"uniqueIndex;size:50;not null"` // 账号，唯一
	Nickname string `json:"nickname" gorm:"size:100"`                     // 用户昵称
	Password string `json:"password" gorm:"size:255;not null"`            // 密码
	CTime    int64  `json:"ctime" gorm:"column:ctime;not null"`           // 创建时间
	UTime    int64  `json:"utime" gorm:"column:utime;not null"`           // 更新时间
}
